package com.zidongxiangxi.rabbit.producer.manager;

import com.zidongxiangxi.rabbit.producer.entity.ProducerSequence;
import com.zidongxiangxi.rabbit.producer.mapper.ProducerSequenceMapper;
import com.zidongxiangxi.rabbit.producer.sql.ProducerSequenceSqlProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * rabbitMQ顺序发送记录管理类
 *
 * @author chenxudong
 * @date 2020/11/07
 */
public class ProducerSequenceManager {
	private final Logger logger = LoggerFactory.getLogger(ProducerSequenceManager.class);

	private final ProducerSequenceSqlProvider sqlProvider;
	private final ProducerSequenceMapper producerSequenceMapper;
	private final JdbcTemplate jdbcTemplate;
	private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	public ProducerSequenceManager(String tableName, JdbcTemplate jdbcTemplate) {
		this.sqlProvider = new ProducerSequenceSqlProvider(tableName);
		this.producerSequenceMapper = new ProducerSequenceMapper();
		this.jdbcTemplate = jdbcTemplate;
		this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
	}

	@Transactional(rollbackFor = Exception.class)
	public void saveProducer(Long id, String application, String groupName, String messageId) {
		jdbcTemplate.update(sqlProvider.getInsertSql(), id, application, groupName, messageId);
	}

	public ProducerSequence getProducer(String application, String messageId) {
		List<ProducerSequence> sequenceMessageList =
				jdbcTemplate.query(sqlProvider.getSelectByMessageIdSql(),
						producerSequenceMapper, application, messageId);
		if (CollectionUtils.isEmpty(sequenceMessageList)) {
			logger.info("can not find sequenceMessage by application[{}] and message[{}]", application, messageId);
			return null;
		}
		return sequenceMessageList.get(0);
	}

	@Transactional(readOnly = true, rollbackFor = Exception.class)
	public String getPreviousMessageId(String application, String groupName, Long id) {
		List<Long> previousIdList = jdbcTemplate.queryForList(sqlProvider.getSelectPreviousIdSql(), Long.class,
				application, groupName, id);
		if (CollectionUtils.isEmpty(previousIdList)) {
			logger.info("can not find previous Ids by id[{}]", id);
			return null;
		}
		Long previousId = previousIdList.get(0);
		List<ProducerSequence> list = jdbcTemplate.query(sqlProvider.getSelectByIdSql(),
				producerSequenceMapper, previousId);
		if (CollectionUtils.isEmpty(list)) {
			logger.info("can not find sequenceMessage by previousId[{}]", previousId);
		}
		return CollectionUtils.isEmpty(list) ? null : list.get(0).getMessageId();
	}

	public List<ProducerSequence> list(Date beforeTime, int size) {
		return jdbcTemplate.query(sqlProvider.getListSql(), producerSequenceMapper, beforeTime, size);
	}

	@Transactional(rollbackFor = Exception.class)
	public boolean deleteByIds(List<Long> ids) {
		Map<String, Object> args = new HashMap<>(1);
		args.put("ids", ids);
		return namedParameterJdbcTemplate.update(sqlProvider.getDeleteSql(), args) > 0;
	}
}
